package cn.lynch.bbs.dao;

import java.util.Collection;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

public class PropertyFilter {
	
	private DetachedCriteria criteria;
	
	private PropertyFilter(Class<?> clz) {
		this.criteria = DetachedCriteria.forClass(clz);
	}
	
	
	public static PropertyFilter createFilter(Class<?> clz) {
		PropertyFilter filter = new PropertyFilter(clz);
		return filter;
	}
	
	public PropertyFilter idEq(Object value) {
		return addCriterion(Restrictions.idEq(value));
	}
	
	public PropertyFilter eq(String propertyName, Object value) {
		return addCriterion(Restrictions.eq(propertyName, value));
	}
	
	public PropertyFilter ne(String propertyName, Object value) {
		return addCriterion(Restrictions.ne(propertyName, value));
	}
	
	public PropertyFilter like(String propertyName, Object value) {
		return addCriterion(Restrictions.like(propertyName, value));
	}
	
	public PropertyFilter ilike(String propertyName, String value) {
		return addCriterion(Restrictions.ilike(propertyName, value, MatchMode.ANYWHERE));
	}
	
	public PropertyFilter ilike(String propertyName, String value, MatchMode matchMode) {
		return addCriterion(Restrictions.ilike(propertyName, value, matchMode));
	}
	
	public PropertyFilter gt(String propertyName, Object value) {
		return addCriterion(Restrictions.gt(propertyName, value));
	}
	
	public PropertyFilter lt(String propertyName, Object value) {
		return addCriterion(Restrictions.lt(propertyName, value));
	}
	
	public PropertyFilter le(String propertyName, Object value) {
		return addCriterion(Restrictions.le(propertyName, value));
	}
	
	public PropertyFilter ge(String propertyName, Object value) {
		return addCriterion(Restrictions.ge(propertyName, value));
	}
	
	public PropertyFilter between(String propertyName, Object lo, Object hi) {
		return addCriterion(Restrictions.between(propertyName, lo, hi));
	}
	
	public PropertyFilter in(String propertyName, Object[] values) {
		return addCriterion(Restrictions.in(propertyName, values));
	}
	
	public PropertyFilter in(String propertyName, Collection<?> values) {
		return addCriterion(Restrictions.in(propertyName, values));
	}
	
	public PropertyFilter isNull(String propertyName) {
		return addCriterion(Restrictions.isNull(propertyName));
	}
	
	public PropertyFilter isNotNull(String propertyName) {
		return addCriterion(Restrictions.isNotNull(propertyName));
	}
	
	private PropertyFilter addCriterion(Criterion criterion) {
		criteria.add(criterion);
		return this;
	}
	
	public PropertyFilter groupBy(String propertyName) {
		criteria.setProjection(Projections.groupProperty(propertyName));
		return this;
	}
	
	public PropertyFilter asc(String propertyName) {
		criteria.addOrder(Order.asc(propertyName));
		return this;
	}
	
	public PropertyFilter desc(String propertyName) {
		criteria.addOrder(Order.desc(propertyName));
		return this;
	}
	
	public DetachedCriteria getCriteria() {
		return criteria;
	}
	
}
